package com.demo.proxy;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.List;

public class ProxyTest {

	// 逆向工程
	public static void main(String[] args) throws Exception, Exception {
		Class clazzProxy = Proxy.getProxyClass(ArrayList.class.getClassLoader(), 
				                                                           ArrayList.class.getInterfaces());
		/*System.out.println("类的字节码名称:"+clazzProxy.getName());
		System.out.println("代理类" + clazzProxy.getName() + "的父类：" + clazzProxy.getSuperclass().getName());
		Class[] clazzInter  = clazzProxy.getInterfaces();
		for (Class class1 : clazzInter) {
			System.out.println("实现的接口:"+class1.getName());
		}
		System.out.println("代理类" + clazzProxy.getName() + "的访问修饰符：" + clazzProxy.getModifiers());
		//解析代理类的构造方法
		Constructor[] cs = clazzProxy.getDeclaredConstructors();
		for (Constructor constructor : cs) {
			System.out.println("构造方法名称:"+constructor.getName());
			//获取构造方法的参数
			Class[] clazz = constructor.getParameterTypes();
			for (Class class1 : clazz) {
				System.out.println("\t参数类型:"+class1.getName());
			}
		}
		//解析代理类的方法
		Method[] methods = clazzProxy.getMethods();
		for (Method method : methods) {
			System.out.println(method.getName());
		}*/
		//怎么创建对象 1. clazzProxy.newInstance() 2. Constructor
		Constructor c = clazzProxy.getConstructor(InvocationHandler.class);
		List list = (List)c.newInstance( new MyInvocationHandler() );
		list.add("aaa");
		list.remove("bbb");
	}
	static class MyInvocationHandler implements InvocationHandler{
		private ArrayList target = new ArrayList();
		@Override
		public Object invoke(Object proxy, Method method, Object[] args)
				throws Throwable {
			System.out.println("开始执行:"+method.getName());
			Object rev = method.invoke(target, args);
			System.out.println(method.getName()+"返回值:"+rev);
			System.out.println("结束执行:"+method.getName());
			return rev;
		}
		
	}
}
